package Camera;

import javax.vecmath.Vector3d;

public abstract class Camera {
	 
	private Vector3d up;
	private Vector3d cameraVector;
	private Vector3d right;
	
	public Camera ( Vector3d eye, Vector3d target, Vector3d up) {
		if (eye == null || target == null || up == null) {
			throw new IllegalArgumentException("null arguments in Camera constructor");
		}
		
		/* eye, target y up son respecto al origen (0,0,0). Este metodo utiliza
		 * operaciones vectoriales para trasladarlos al origen que corresponde 
		 */
		calcCameraVectors(eye, target, up);
	}

	public Vector3d getUp() {
		return new Vector3d(this.up);
	}
	
	public Vector3d getRight() {
		return new Vector3d(this.right);
	}

	public void setCameraVector(Vector3d cameraVector) {
		this.cameraVector = new Vector3d(this.cameraVector);
	}

	public Vector3d getCameraVector() {
		return cameraVector;
	}

	private void calcCameraVectors(Vector3d origin, Vector3d target, Vector3d up) {
		Vector3d auxorigin, auxtarget;
		
		/* Los clona para no modificar las referencias */
		auxorigin = new Vector3d(origin);
		auxtarget = new Vector3d(target);
	
		/* Como origin, target y up tienen su origen en (0,0,0), se modifica su origen
		 * en base a operaciones vectoriales
		 */
		
		auxorigin.negate(); /* V * -1 */
		
		auxtarget.add(auxorigin); /* U - V */
		this.cameraVector = new Vector3d(auxtarget);
		
		/* right = look-direction x (0, 1, 0) */
		
		this.right = new Vector3d();
		this.right.cross(this.cameraVector, new Vector3d(0, 1, 0));
		this.right.normalize();
		
		/* up = look-direction x right */
		this.up = new Vector3d();
		this.up.cross(this.cameraVector, this.right);
		this.up.normalize();
	}
}
